
let { config } = require('../config.js')(runtime, this)
let singletonRequire = require('../lib/SingletonRequirer.js')(runtime, this)

let widgetUtils = singletonRequire('WidgetUtils')
let automator = singletonRequire('Automator')
let commonFunctions = singletonRequire('CommonFunction')
let FloatyInstance = singletonRequire('FloatyUtil')
let logUtils = singletonRequire('LogUtils')
let signFailedUtil = singletonRequire('SignFailedUtil')
let YoloTrainHelper = singletonRequire('YoloTrainHelper')
let WarningFloaty = singletonRequire('WarningFloaty')
let NotificationHelper = singletonRequire('Notification')
let MyUtil = require('../utils.js')
let myutil = new MyUtil()
let BaseSignRunner2 = require('./BaseSignRunner2.js')
let jingDongBeans = require('./JingDongBeans.js')

function myApp(runner) {
  let _app = app
  this.launchPackage = function (packageName) {
    logUtils.debugInfo(['launchPackage'])
    // sleep(1000)
    // _app.launchPackage(packageName)
    shuangKai(runner)
  }
  this.startActivity = function (intent) {
    _app.startActivity(intent)
    shuangKai(runner)
  }
}

function appendFilter(selector) {
  return selector.classNameContains('Image')
}

function shuangKai(runner) {
  home()
  sleep(500)
  home()
  sleep(500)
  home()
  sleep(2000)
  let ele = widgetUtils.widgetGetById('.*?clear_icon')
  if (ele) {
    runner.displayButtonAndClick(ele, '清理')
  }
  let shuangKai = textMatches(/京东/).find()
  let len = shuangKai?shuangKai.length:0
  runner.pushLog(`双开应用 len=${len}`)
  if (shuangKai&&shuangKai.length>0) {
    let task = runner.getMainTask()
    let name = task?task.name:`taskName:${runner.name}`
    let index = Math.min(shuangKai.length-1, (task&&task.number||0))
    runner.pushLog(`点击第${index}个 ${name}`)
    console.log('双开', shuangKai.length, index, task)
    automator.click(shuangKai[index].bounds().centerX(), shuangKai[index].bounds().centerY() - 50)
    widgetUtils.widgetWaiting('首页', '双开找到首页', 5000)
    // for (let i=0;i<3;++i) {
    //   runner.displayButtonAndClick(shuangKai[index], `京东${i}`)
    //   sleep(2000)
    //   if (commonFunctions.myCurrentPackage() === runner._package_name) {
    //     break
    //   }
    //   runner.pushLog(commonFunctions.myCurrentPackage())
    //   if (i == 0) {
    //     automator.click(shuangKai[index].bounds().centerX(), shuangKai[index].bounds().centerY() - 50)
    //     sleep(2000)
    //     if (commonFunctions.myCurrentPackage() === runner._package_name) {
    //       break
    //     }
    //     runner.pushLog(commonFunctions.myCurrentPackage())
    //   }
    // }
  }
}
function getAncestorsWithin3Levels(node) {
    let ancestors = [];
    let current = node;
    for (let i = 0; i < 3 && current != null &&current.parent; i++) {
        current = current.parent(); 
        if (current)  ancestors.push(current); 
    }
    return ancestors;
}
 
function hasCommonParentWithin3Levels(node1, node2) {
    const list1 = getAncestorsWithin3Levels(node1);
    const list2 = getAncestorsWithin3Levels(node2);
 
    for (let i = 0; i < list1.length;  i++) {
        for (let j = 0; j < list2.length;  j++) {
            if (list1[i].bounds().equals(list2[j].bounds())) {
                return true;
            }
        }
    }
    return false;
}
function boundsInsideText(a,b,c,d, callback, btn) {
  let lst = textMatches(/.*/).boundsInside(a,b,c,d).find()
  if (!lst) lst = descMatches(/.*/).boundsInside(a,b,c,d).find() 
  if (callback) {
    return callback(lst)
  }
  let t = ''
  lst.forEach(e => {
    if (btn&&btn.parent&&!hasCommonParentWithin3Levels(btn, e)) {
      return
    }
      if (t) t += '|'
      t += e.text()
  })
  return t
}

function getTaskInfo(btn, sub, callback, baseRunner) {
  logUtils.debugInfo(['btn={},{}', btn.text()||btn.desc(), btn.bounds()])
  sub = sub||140
  let rect = btn.bounds()
  let a = 0
  let b = rect.centerY()-sub
  let c = device.width
  let d = rect.centerY()+sub
  if (baseRunner) {
    baseRunner.addRectangle('任务信息', [a,b,c-a,d-b])
  } else {
    let fltType = 'rect' 
    WarningFloaty.addRectangle('任务信息', [a,b,c-a,d-b], null, fltType)
    sleep(1000)
    WarningFloaty.clearAll(fltType)
  }
  return boundsInsideText(a,b,c,d, callback, btn)
}

function BeanCollector2 () {
  let _this = this
  jingDongBeans.constructor.call(this)
  let _app = new myApp(_this)
  const _package_name = 'com.jingdong.app.mall'

  this.task = config.supported_signs.find(task => {
    return ['JingDongSign2', ].includes(task.taskCode)
  })
  this.subTasks = this.task ? this.task.subTasks : []
  console.log('subTasks=',this.subTasks)
  const binSign = this.subTasks.filter(task => task.taskCode == 'binSign')[0]
  const plantBean = this.subTasks.filter(task => task.taskCode == 'plantBean')[0]
  const binTask = this.subTasks.filter(task => task.taskCode == 'binTask')[0]
  const SIGN = this.subTasks.filter(task => task.taskCode == 'beanSign')[0]
  const BEAN = this.subTasks.filter(task => task.taskCode == 'plantBean')[0]
  const DOUBLE_SIGN = this.subTasks.filter(task => task.taskCode == 'doubleSign')[0]
  const DRUG_SIGN = this.subTasks.filter(task => task.taskCode == 'drugSign')[0]
  const LUCKY_SIGN = this.subTasks.filter(task => task.taskCode == 'luckySign')[0]
  const GAME_CENTER = this.subTasks.filter(task => task.taskCode == 'gameCenter')[0]
  const DAILY_TASK = this.subTasks.filter(task => task.taskCode == 'dailyTask')[0]
  const fruits = this.subTasks.filter(task => task.taskCode == 'fruits')[0]
  this.loopCounter = this.createStoreOperator('loopCounter', { count: 0, maxCount: 20 })

  const FIND_TIMEOUT = device.model == 'Redmi Note 5' ? 3500 : 2500
  const notifyOper = this.notifyOper()

  const HOME_PAGE_MSG =  {
      and: {
        '我的': [0, device.height*0.8, device.width, device.height*0.2],
        '购物车': [0, device.height*0.8, device.width, device.height*0.2],
        '消息|新品|逛': [0, device.height*0.8, device.width, device.height*0.2],
      }
    }
  function swipeLeftOrRight(left) {
    if (left) {
        swipe(device.width-200, device.height/2-100, 200, device.height/2, 1000)
    } else {
        swipe(200, device.height/2, device.width-200, device.height/2-100, 1000)
    }
    sleep(2000)
  }
  function clearByDesktopBtn(pkg) {
    home()
    sleep(2000)
    // for (let i=0;i<3;++i) {
    //   swipeLeftOrRight(1)
    // }
    let name = app.getAppName(pkg)
    let ele = widgetUtils.widgetGetOne(name, FIND_TIMEOUT)
    if (!ele) return
    automator.click(ele.bounds().centerX(), ele.bounds().centerY() - 360)
    _this.pushLog('已经清理进程')
  }
  function openHome () {
    let pkgName = _this.getPackage()
    _this.pushLog(`重开应用 当前package${pkgName},目标${_package_name}`)
    if (pkgName !== _package_name) {
      recents()
      sleep(2000)
      let ele = widgetUtils.widgetGetOne('本机共有.*', FIND_TIMEOUT)
      if (ele) {
        _this.displayButtonAndClick(ele, '清除进程')
        _this.pushLog('已清理进程')
      } else {
        clearByDesktopBtn(pkgName)
      }
    }
    if (commonFunctions.myCurrentPackage() != pkgName) {
      _app.launchPackage(pkgName)
      _this.pushLog('打开京东APP')
      sleep(2000)
    }
    if (pkgName !== _package_name) { // blackbox
      let task = _this.getMainTask()
      for (let i=0;i<task.number;++i) {
        swipeLeftOrRight(1)
      }
      _this.clickText('京东', FIND_TIMEOUT, null, true)
      widgetUtils.widgetWaiting('首页', 30000)
    }
    let msg = HOME_PAGE_MSG
    _this.backTo(msg)
      let myWidget = descContains('首页').boundsInside(0, config.device_height * 0.8, config.device_width, config.device_height).findOne(1000)
    if (myWidget) {
      _this.pushLog('点击 首页 控件')
      let ret = _this.displayButtonAndClick(myWidget, '首页')
      sleep(3000)
      return ret
    }
    return false
  }
  this.getPackage = function () {
    let task = this.getMainTask()
    let pkg = (task&&task.package) || _package_name
    if (pkg.includes(',')) {
      for (let tmp of pkg.split(',')) {
        let name = app.getAppName(pkg)
        if (name) {
          task.package = tmp
          task.packageName = name
          pkg = tmp
          break
        }
      }
    }
    return pkg
  }
  this.getDialogText = function () {
    return '离开会场|开心收下|立即领取|狠心离开|残忍退出|继续寻宝|我?知道了|点击领奖|直接退出|关闭任务面板'
  }
  this.getTimeout = function () {
    return FIND_TIMEOUT
  }

  this.testf = function () {
    this.plantFruit()
    this.天天领红包()
    sleep(5000)
    exit()
  }

  this.exec = function () { 
    jingDongBeans.setApp(_app)
    if (this.test) {
      jingDongBeans.setTest()
      // this.testf()
    }
    home()
    sleep(500)
    home()
    sleep(2000)
    const loopValue = this.loopCounter.getValue()
    this.pushLog('运行次数：'+loopValue.count)
    if (loopValue.count > loopValue.maxCount) {
      return
    }
    this.loopCounter.updateStorageValue(storeValue => storeValue.count += 1)
    this.getUserInfo()
    this.binSignTask()
    this.binDayTask()
    this.plantBeanTask()
    this.plantFruit()
    this.天天领红包()
    //jingDongBeans.exec()
  }
  this.getUserInfo = function () {
    openHome()
    this.pushLog('获取用户信息')
    let lst = [
      {
        region: HOME_PAGE_MSG.and.我的,
        text: '我的',
        waitFor: ['红包',],
        sleep: (info) => {
          sleep(2000)
          let ele = className('LinearLayout').idContains("feature:id/pj").findOnce()
          if (!ele) {
            ele = className('LinearLayout').idContains("feature:id/mg").findOnce()
          }
          let txt = '\n'
          if (!ele) {
            ele = _this.findText('设置', [0,0, device.width, 200], FIND_TIMEOUT)
            let a=0, b=100, c=device.width/2, d=device.height*0.1125
            if (ele) {
              b = ele.bounds().bottom+50;d=b+200
            }
            _this.addRectangle('账号信息', [a,b,c-a,d-b])
            txt = boundsInsideText(a,b,c,d, null, null)
          } else {
            txt = this.allText(ele)
          }
          this.pushLog('账号信息:'+txt)
          notifyOper.appendMsg('账号：' + txt+'\n')
          ele = this.findText(/待收货/, null, FIND_TIMEOUT)
          if (!ele) {
              return
          }
          let p = ele.parent ? ele.parent() : ele
          let a=0,b=0,c=0,d=0
          if (ele.parent) {
            a=ele.parent().bounds().left, b=ele.parent().bounds().top,
            c = ele.parent().bounds().right, d = ele.parent().bounds().bottom
          } else {
            a=ele.bounds().left-20, b=ele.bounds().top-20,
            c = ele.bounds().right-20, d = ele.bounds().bottom+20
          }
          txt = boundsInsideText(a,b,c,d)
          if (!txt.match(/\d+/)) {
              logUtils.debugInfo(['没有待收货'])
              this.clickText('首页', FIND_TIMEOUT, null, true)
              return
          }
          this.displayButtonAndClick(ele, '待收货')
          let eles = className('LinearLayout').idContains("com.jd.lib.ordercenter.feature").depth(15).find()
          eles.forEach(item => {
              if (item.childCount() === 4) {
                let a=item.bounds().left, b=item.bounds().top,
                c = item.bounds().right, d = item.bounds().bottom
                  let txt = boundsInsideText(a,b,c,d)
                  notifyOper.appendMsg('快递：' + txt + '\n')
              }
          })
          this.backTo(HOME_PAGE_MSG)
          this.clickText('首页', FIND_TIMEOUT, null, true)
        }
      },
    ]
    this.pipeLine(lst)
  }
  this.closePopup = function () {
    this.closeDialogByImage()
  }
  function doBeanSign(restartCount) { 
    if (restartCount > 3) return
    if (!openHome()) {
      _this.pushLog('打开京东失败')
      return
    }
    let lst = [
      {
        region: [0,0,device.width, device.height * 0.4],
        text: '秒杀',
        waitFor: ['(京豆)?可抵',],
        sleep: function (info) {
          sleep(5000)
        }
      },
      {
        id: 'homeSignButton',
        text: /签到领豆|赚更多.*?/,
        region: [0,0,device.width, device.height * 0.5],
        waitFor: ['(盲盒)?等级.*', '(京豆)?可抵'],
        sleep: function(info) {
          if (_this.findText(info.waitFor[0], null, FIND_TIMEOUT)) {
            sleep(1000)
            return
          }
          _this.clickText(info.text, FIND_TIMEOUT, info.region, true)
        }
      },
    ]
    sleep(5000)
    _this.pipeLine(lst, doBeanSign, restartCount)
    return lst
  }
  this.binSignTask  = function () {
    if (this.isSubTaskExecuted(binSign)) {
      this.pushLog('今日已完成签到')
      return true
    }
    let lst = doBeanSign()
    if (lst&&lst[1].find&&binSign) {      
      this.setSubTaskExecuted(binSign)
    }
  }
  this.binDayTask = function (restartCount) {
    if (restartCount > 3) return
    if (this.isSubTaskExecuted(binTask)) {
      this.pushLog('今日已完成京豆任务')
      return true
    }
    this.pushLog('开始京豆任务')
    let txtInTaskPage = '(盲盒)?等级.*'
    if (!this.findText(txtInTaskPage, null , FIND_TIMEOUT)) {
      let lst = doBeanSign()
      if (!lst||!lst[1].find) {
        this.pushLog('没打开京豆任务列表')
        return false
      }
    }
    that = this
    let lst = [
      {
        boundsInside: [0, device.height*0.5, device.width, device.height],
        text: '去完成|去领取',
        backTo: {
          '(盲盒)?等级.*': [0, device.height*0.5, device.width, device.height*0.5],
          '京豆可.*|签到领豆|赚更多.*?': [0,device.height * 0.1,device.width, device.height * 0.5],
          and: HOME_PAGE_MSG.and,
        },
        ocr: true,
        blackList: [],
        end: false,
        timeout: device.model == 'Redmi Note 5' ? 4500 : 3500,
        loopFilter:  function(lst, info) {
          let txt = ''
          for (let ele of lst) {
            txt = ele.text()
            info.node = ele
            if (!txt.includes('领取')) {
              that.displayButton(ele, txt)
              txt = getTaskInfo(ele, null, null, that)
              logUtils.debugInfo(['任务:{}', txt])
              that.pushLog(txt)
              if (inBlacks(txt, info.blackList)) {
                txt = ''
                continue
              }
              let match = txt.match(/(\d+)(s|秒)/)
              info.timeout = device.model == 'Redmi Note 5' ? 4500 : 3500
              if (match) {
                info.timeout = parseInt(match[1]) * (device.model == 'Redmi Note 5' ? 1500 : 1000)
              }
              info.hasPop = txt.match('买药') !== null
            }
            that.action(info)
            that.loopCounter.updateStorageValue(storeValue => {
              storeValue.signTaskCount = storeValue.signTaskCount?storeValue.signTaskCount+1:1
            })
            break
          }
          info.end = !txt
        },
        sleep:  function(info) {
          sleep(info.timeout)
          倒计时(info, _this)
          if (_this.clickText('^(马上签到|领)$', FIND_TIMEOUT, null, true)) {
            sleep(info.timeout)
            _this.clickText('签到领京豆', FIND_TIMEOUT, null, true)
          }
          if (info.hasPop) {
            _this.closeDialogByImage(null, 1)
          } else {
            _this.closeDialogByImage(null, 0)
          }
        },
        restart: (info) => {
          if (_this.clickText(txtInTaskPage, FIND_TIMEOUT, null, false)) return
          if (_this.findText('首页', HOME_PAGE_MSG.and.我的, FIND_TIMEOUT) ) {
            _this.binDayTask()
            logUtils.debugInfo(['从首页重新进入'])
            return
          }
          let ele = _this.clickText('赚更多.*?', FIND_TIMEOUT, null, true)
          if (ele) {
            logUtils.debugInfo(['找到了 赚更多.*?，不用重启'])
            sleep(1000)
            return
          }
          info.retry = info.retry? info.retry + 1 : 1
          if (info.retry > 3) return
          _this.pushLog('任务重启')
          commonFunctions.killCurrentApp()
          restartCount = restartCount||1
          _this.binDayTask(++restartCount)
          info.end = true
        }
      },
    ]
    this.pipeLine(lst, this.binDayTask, restartCount)
    if (lst[0].end&&binTask) {      
      this.setSubTaskExecuted(binTask)
    }
    let count = this.loopCounter.getValue().signTaskCount||0
    notifyOper.appendMsg(`秒杀任务数量：${count}\n`)
    this.backTo(HOME_PAGE_MSG)
  }
  this.plantBeanTask = function (restartCount) { 
    if (restartCount > 3) return
    let task = plantBean
    if (this.isSubTaskExecuted(task)) {
      this.pushLog('今日已完成京豆任务')
      return true
    }
    if (!openHome()) {
      _this.pushLog('打开京东失败')
      return
    }
    this.pushLog('开始种豆得豆')
    let txtInTaskPage = '做任务.*?收获值'
    let that = this
    let finished = false
    let lst = [
      {
        region: [0,0, device.width, device.height*0.4],
        text: '种豆得豆',
        waitFor: ['赚收获值',],
        // backTo: '秒杀',
        sleep:  (info) => {
          sleep(_this.getTimeout())
          let dt = new Date()
          if (dt.getDay() === 1 && dt.getHours() > 9) {
            // 收上期
            // myutil.clickText(/上期/)
            if (_this.findText('TZ4l9U.*', null, FIND_TIMEOUT, 2)) {
              _this.clickText('收下京豆', FIND_TIMEOUT, null, true)
              sleep(_this.getTimeout())
            } else if (_this.clickText('收下京豆', FIND_TIMEOUT, null, true) ) {                
              sleep(_this.getTimeout())
            }
          }
          if (_this.clickText('点击领奖.*', 5000, [0,device.height*0.5, device.width, device.height*0.3], true)) {
            sleep(2000)
            _this.closeDialogByImage(null, 2)
            _this.clickText('明天继续.*|我知道了', 5000, [0,device.height*0.5, device.width, device.height*0.3], true)
          }
        }
      },
      {
        region: [0,device.height*0.5, device.width, device.height * 0.4],
        text: '赚收获值$',
        waitFor: [txtInTaskPage,],
        notFound: function() {
          let ele = _this.findText('好友助力', [0,device.height*0.3, device.width, device.height * 0.4], FIND_TIMEOUT, 2)
          if (!ele) {
            return null
          }
          let bounds = ele.bounds()
          bounds.top += 100
          bounds.bottom += 100
          return _this.wrapOcrPointWithBounds(bounds, '赚收获值')
        },
        timeout: device.model == 'Redmi Note 5' ? 4500 : 2000,
      },
      {
        boundsInside: [0, device.height*0.3, device.width, device.height],
        beforeFind: function () {
          let ele = [device.width/2,device.height*0.8, '种豆任务列表']
          _this.swipeWidget(ele, -10, -300)
          ele = [device.width/2,device.height*0.8-300, '种豆任务列表']
          _this.swipeWidget(ele, 10, 300)
          ele = _this.findText(txtInTaskPage, null, FIND_TIMEOUT)
          if (ele) {
            this.boundsInside[1] = ele.bounds().bottom
          }
          sleep(1000)
        },
        text: '去逛逛|去领取|去签到|去看看|逛一逛|去关注|去完成',
        backTo: {
          '做任务.*': [0, 0, device.width, device.height*0.5], // txtInTaskPage
          and: HOME_PAGE_MSG.and,
          '我的收获值.*': [0, 0, device.width, device.height*0.5],
        },
        blackList: ['好友助力', '最牛挑战', '提醒', '百度','首页'],
        taskCount: {max:10,},
        desc: '', // 任务描述内容
        end: false,
        timeout: device.model == 'Redmi Note 5' ? 12000 : 12000,
        loopFilter:  this.finishTasks,
        sleep:  (info) => {
          _this.loopCounter.updateStorageValue(storeValue => {
            storeValue.beanTaskCount = storeValue.beanTaskCount?storeValue.beanTaskCount+1:1
          })
          _this.pushLog(`sleep ${info.timeout}`)
          let name = ['关注频道', '关注店铺'].filter(item => info.desc.includes(item))
          if (name.length > 0) {
            name = name[0]==='关注频道'?'进入并关注':'进店并关注'
            widgetUtils.widgetWaiting(name, '等待页面加载', 30000)
            for (let i=0;i<6;i++) {
              _this.clickText(name, FIND_TIMEOUT, null, true)
              sleep(3000)
              this.backTo(name)
              sleep(1000)
            }
            return
          }
          sleep(info.timeout)
          倒计时(info, _this)
        },
        restart: (info) => {
          if (_this.clickText(txtInTaskPage, FIND_TIMEOUT, null, false)) return
          let ele = _this.clickText('更多任务', FIND_TIMEOUT, null, true)
          if (ele) {
            logUtils.debugInfo(['找到了 更多任务，不用重启'])
            sleep(1000)
            return
          }
          info.retry = info.retry? info.retry + 1 : 1
          if (info.retry > 3) return
          _this.pushLog('任务重启')
          commonFunctions.killCurrentApp()
          restartCount = restartCount||1
          _this.plantBeanTask(++restartCount)
          info.end = true
        },
        collect: (info) => {
          automator.click(device.width/2, 100)
          _this.closeDialogByImage(null, 2)
          sleep(2000)
          _this.closeDialog(txtInTaskPage, 2000)
          sleep(2000)
          _this.collectBeanFriends()
          sleep(1000)
          finished = _this.collectBeanTask() > 0
        }
      },
    ]
    this.pipeLine(lst, this.plantBeanTask, restartCount)
    this.pushLog('结束种豆得豆')
    let count = this.loopCounter.getValue().beanTaskCount||0
    notifyOper.appendMsg(`种豆得豆任务数量：${count}\n`)
    this.backTo(HOME_PAGE_MSG)
    if (finished&&task) {      
      this.setSubTaskExecuted(task)
    }
  }
  function getRandomItem(arr) {
    if (arr.length === 0) {
      return null
    }
    const randomIndex = Math.floor(Math.random() * arr.length);
    return arr[randomIndex];
  }
  this.collectBeanFriends = function () { 
    sleep(1000)
    let region = [0, device.height*0.7, device.width, device.height*0.2]
    this.addRectangle('好友范围', region)
    let appendFilter = (matcher) => {
      return matcher.boundsInside(region[0],region[1],region[0]+region[2],region[1]+region[3])
    }
    let node = null
    for (let i=0;i<5; ++i) {
      let nodes = widgetUtils.widgetGetAll('3', 5000, null, appendFilter)
      this.pushLog('好友数量' + (nodes!==null?nodes.length:0))
      if (!nodes) break
      node = nodes[0]
      if (node.bounds().left > device.width) {
        this.swipeWidget(node, device.width-node.bounds().left, 0)
        sleep(1000)
      }
      this.displayButtonAndClick(node, '好友')
      sleep(2000)
      this.collectBeanTask('点击领取')
      sleep(1000)
    }
    if (node) automator.back()
  }
  this.collectBeanTask = function(regx) {
    let region = [0, device.height*0.1, device.width, device.height*0.4]
    this.addRectangle('分数范围', region)
    let appendFilter = (matcher) => {
      return matcher.boundsInside(region[0],region[1],region[0]+region[2],region[1]+region[3])
    }
    let clicked30 = false
    let zeroCount = 0
    let taskCount = 0
    for (let i = 0; i < 10; i++) {
      let nodes = widgetUtils.widgetGetAll(regx||/\+?[1-9]\d*/, 5000, null, appendFilter)
      if (!nodes || nodes.length === 0) {
        zeroCount++
        if (zeroCount >= 3) {
          break
        }
        continue
      }
      let count = 0
      nodes.forEach(node => {
        let txt = this.allText(node.parent())
        this.pushLog(txt)
        if (txt.includes('50')) {
          if (txt.includes('明日')) {
            return
          }
          clicked30 = true
        }
        count++
        taskCount++
        this.displayButtonAndClick(node, '分数')
        this.closeDialogByImage(null, 16)
        sleep(1000)
      })
      if (count === 0) {
        zeroCount++
        if (zeroCount >= 3) {
          break
        }
        continue
      }
      if (regx) break
    }
    return taskCount
  }
  this.plantFruit = function (restartCount) { 
    if (restartCount > 3) return
    let task = fruits
    if (this.isSubTaskExecuted && this.isSubTaskExecuted(task)) {
      this.pushLog('今日已完东东农场')
      return true
    }
    if (!openHome()) {
      _this.pushLog('打开京东失败')
      return
    }
    sleep(this.getTimeout())
    this.pushLog('开始东东农场')
    let txtInTaskPage = '做任务.*?领水滴'
    that = this
    let collect = false
    let 再浇 = [0, device.height*0.4, device.width, device.height*0.4]
    let lst = [
      {
        region: [0,0,device.width, device.height * 0.4],
        text: '东东农场',
        waitFor: ['再浇.*', "攻略"],
        sleep:  (info) => {
          that.closeDialogByImage(null, 1)
          console.log('纠正位置', info.waitFor[0])
          let ele = _this.findText(info.waitFor[0], null, FIND_TIMEOUT)
          if (!ele) {
            info.end = _this.findText('.*?繁忙.*', null, FIND_TIMEOUT)
            console.log('end?', info.end)
            return
          }
          notifyOper.appendMsg(ele.text() + '\n')
          // 再浇[1] = ele.bounds().top - 1
          // 再浇[3] = ele.bounds().height() + 1
          that.addRectangle('再浇', 再浇)
          lst[1].region[1] = ele.bounds().bottom
          lst[3].region[1] = ele.bounds().bottom
          sleep(3000)
        },
      },
      {
        region: [0,device.height*0.55, device.width, device.height * 0.3],
        text: '签到',
        ocr: true,
        id: 'expo_sign_icon',
        waitFor: ['签到记录','第\\d天'],
        notFound: function () {
          let ele = _this.findText('点击开炮', [0,device.height*0.3, device.width, device.height * 0.4], FIND_TIMEOUT, 2)
          if (!ele) {
            return null
          }
          let bounds = ele.bounds()
          bounds.top += 200
          bounds.bottom += 200
          return _this.wrapOcrPointWithBounds(bounds, '假签到')
        },
      },
      {
        region: [0,device.height*0.3, device.width, device.height * 0.4],
        text: '点击签到.*|已连续.*',
        waitFor: ['明天再来', '已签到'],
        backTo: {
          '再浇.*': 再浇,
          "领水滴":[0,device.height*0.5,device.width,device.height*0.3],
          and: HOME_PAGE_MSG.and,
        },
        notFound: function () {
          _this.backTo(this.backTo)
        },
      },
      {
        region: [0,device.height*0.55, device.width, device.height * 0.3],
        beforeFind: function () {
          let ele = _this.findText('\\d+g', this.region, FIND_TIMEOUT, 1)
          if (!ele) {
            _this.pushWarningLog('没有找到水滴数量')
            return
          }
          let water = parseInt(ele.text())
          if (water > 10*20) {
            return
          }
          _this.pushWarningLog('水滴不足')
          lst[4].blackList.push('浇水')
        },
        text: '领水滴',
        id: 'expo_task_icon',
        ocr: true,
        waitFor: [txtInTaskPage,],
        sleep:  (info) => {
          console.log('纠正位置', info.waitFor[0])
          let ele = widgetUtils.widgetGetOne(info.waitFor[0], FIND_TIMEOUT)
          if (!ele) {
            info.end = widgetUtils.widgetGetOne('.*?繁忙.*', FIND_TIMEOUT)
            return
          }
          lst[4].boundsInside[1] = ele.bounds().bottom
          sleep(3000)
        },
      },
      {
        boundsInside: [0, device.height*0.3, device.width, device.height],
        beforeFind: function () {
          let ele = [device.width/2,device.height*0.8, '任务列表']
          _this.swipeWidget(ele, -10, -300)
          ele = [device.width/2,device.height*0.8-300, '任务列表']
          _this.swipeWidget(ele, 10, 300)
          ele = _this.findText(txtInTaskPage, null, FIND_TIMEOUT)
          if (ele) {
            this.boundsInside[1] = ele.bounds().bottom
          }
          _this.addRectangle("任务列表", [this.boundsInside[0], this.boundsInside[1], device.width, device.height-this.boundsInside[1]])
          sleep(1000)
        },
        text: '去完成|去逛逛|去领取|去签到|去看看|逛一逛|去关注|去浇水',
        backTo: {
          '做任务.*?领水滴': [0, 0, device.width, device.height*0.5],
          '再浇.*': 再浇,
          '东东农场': [0,0, device.width, device.height*0.5],
          and: HOME_PAGE_MSG.and,
        },
        blackList: ['好友助力', '开启定时','下单', '中国移动', '健康抽免单'],
        taskCount: {max:10,},
        desc: '', // 任务描述内容
        end: false,
        timeout: device.model == 'Redmi Note 5' ? 5000 : 3000,
        ocr: true,
        loopFilter:  this.finishTasks,
        sleep:  (info) => {
          _this.loopCounter.updateStorageValue(storeValue => {
            storeValue.fruitTaskCount = storeValue.fruitTaskCount?storeValue.fruitTaskCount+1:1
          })
          _this.pushLog(`sleep ${info.timeout}`)
          sleep(500)
          if ((info.node&&info.node.text().includes('领取'))||info.desc.includes('领取')) {
            sleep(info.timeout)
            return
          }
          if (widgetUtils.widgetGetOne('东东农场', FIND_TIMEOUT)&&!widgetUtils.widgetGetOne(txtInTaskPage, FIND_TIMEOUT)) {
            _this.pushLog('可能出现了弹窗')
            sleep(3000)
            _this.closeDialogByImage(null, 1)
            _this.clickText(lst[3].text, FIND_TIMEOUT, lst[3].region, true)
            return
          }
          sleep(info.timeout)
        },
        restart: (info) => {
          if (_this.clickText(txtInTaskPage, FIND_TIMEOUT, null, false)) return
          let ele = _this.clickText('领水滴', FIND_TIMEOUT, null, true)
          if (ele) {
            _this.pushLog('找到了 更多任务，不用重启')
            sleep(1000)
            return
          }
          info.retry = info.retry? info.retry + 1 : 1
          if (info.retry > 3) return
          _this.pushLog('任务重启')
          commonFunctions.killCurrentApp()
          restartCount = restartCount||1
          _this.plantFruit(++restartCount)
          info.end = true
        },
        collect: (info) => {
          this.closeDialogByImage(null, 2)
          this.closeDialog(txtInTaskPage, 2000)
          sleep(1000)
          collect = true
          let ele = _this.findText('\\d+g', this.region, FIND_TIMEOUT, 1)
          if (!ele) {
            _this.pushWarningLog('没有找到水滴数量')
            return
          }
          let water = parseInt(ele.text())
          for (let i=0;i<30&&water>500; ++i) {
            _this.clickText('连浇5次', _this.getTimeout(), this.region)
            water -= 50
            sleep(1000)
            _this.closeDialogByImage(null, 1)
          }
        }
      },
    ]
    this.pipeLine(lst, this.plantFruit, restartCount)
    this.pushLog('结束东东农场')
    let count = this.loopCounter.getValue().fruitTaskCount||0
    notifyOper.appendMsg(`东东农场任务数量：${count}\n`)
    this.backTo(HOME_PAGE_MSG)
    if (collect&&task) {
      this.setSubTaskExecuted && this.setSubTaskExecuted(task)
    }
  }
  this.天天领红包 = function(restartCount) {
    if (restartCount > 3) return
    if (!openHome()) {
      _this.pushLog('打开京东失败')
      return
    }
    sleep(this.getTimeout())
    this.pushLog('开始天天领红包')
    let txtInTaskPage = '累计领红包'
    that = this
    let collect = false
    // let ele = this.findText('种豆得豆', null, this.getTimeout())
    // if (!ele) {
    //   this.pushWarningLog('没找到种豆得豆')
    //   return
    // }
    // let point = [device.width-200, ele.bounds().centerY()]
    // this.swipeWidget(point, 0-point[0]+100, 10)
    let lst = [
      {
        region: [0,device.height * 0.1,device.width, device.height * 0.3],
        text: '新品',
        waitFor: ['.*gif', "新品试用"],
        sleep:  (info) => {
          that.closeDialogByImage(null, 1)
          sleep(3000)
        },
        notFound: function ()  {
          return _this.findText(this.text, null, FIND_TIMEOUT)
        }
      },
      {
        region: [device.width*0.5,device.height * 0.1,device.width*0.5, device.height * 0.2],
        text: '.*gif|天天领红包 ',
        ocr: true,
        waitFor: ['累计领红包','红包可抵现'],
        timeout: 3000,
      },
      {
        boundsInside: [0, device.height*0.3, device.width, device.height],
        beforeFind: function () {
          let ele = [device.width/2,device.height*0.8, '任务列表']
          _this.swipeWidget(ele, -10, -300)
          ele = [device.width/2,device.height*0.8-300, '任务列表']
          _this.swipeWidget(ele, 10, 300)
          ele = _this.findText(txtInTaskPage, null, FIND_TIMEOUT)
          if (ele) {
            this.boundsInside[1] = ele.bounds().bottom
          }
          _this.addRectangle("任务列表", [this.boundsInside[0], this.boundsInside[1], device.width, device.height-this.boundsInside[1]])
          sleep(1000)
        },
        text: '去完成|去?领取$',
        backTo: {
          '累计领红包': [0, device.height*0.4, device.width, device.height*0.5],
          '新品': [0,0, device.width, device.height*0.3],
          and: HOME_PAGE_MSG.and,
        },
        blackList: ['好友助力', '开启定时','下单'],
        taskCount: {max:10,},
        desc: '', // 任务描述内容
        end: false,
        timeout: device.model == 'Redmi Note 5' ? 5000 : 3000,
        ocr: true,
        loopFilter:  this.finishTasks,
        sleep:  (info) => {
          _this.loopCounter.updateStorageValue(storeValue => {
            storeValue.redpTaskCount = storeValue.redpTaskCount?storeValue.redpTaskCount+1:1
          })
          _this.pushLog(`sleep ${info.timeout}`)
          sleep(info.timeout)
          倒计时(info, _this)
        },
        restart: (info) => {
          if (_this.clickText(txtInTaskPage, FIND_TIMEOUT, null, false)) return
          let ele = _this.clickText(lst[1].text, FIND_TIMEOUT, null, true)
          if (ele) {
            _this.pushLog('找到了 任务，不用重启')
            sleep(1000)
            return
          }
          _this.pushLog('任务重启')
          commonFunctions.killCurrentApp()
          restartCount = restartCount||1
          _this.天天领红包(++restartCount)
          info.end = true
        },
        collect: (info) => {
          this.closeDialogByImage(null, 2)
          this.closeDialog(txtInTaskPage, 2000)
          sleep(1000)
          collect = true
        }
      },
    ]
    this.pipeLine(lst, this.天天领红包, restartCount)
    this.pushLog('结束天天领红包')
    let count = this.loopCounter.getValue().redpTaskCount||0
    notifyOper.appendMsg(`天天领红包任务数量：${count}\n`)
    this.backTo(HOME_PAGE_MSG)
  }
  function 倒计时(info, that) {
    let loop = 0
    while (info.loopFilter&&loop++<30 && that.findText('继续浏览\\d+', null, 1000)) {
      sleep(1000)
    }
  }
  function inBlacks(txt, blackList) {
    if (!blackList) return false
    return blackList.some(black => txt.match(black))
  }
  this.finishTasks = function (lst, info) {
    console.log("task len", lst.length)
    if (info.endCount === undefined) {
      info.endCount = 0
    } else {
      info.endCount++
    }
    info.end = info.endCount >= 3
    lst.sort((a, b) => a.bounds().top - b.bounds().top)
    for (let ele of lst) {
      if (ele.bounds().bottom > device.height)  continue
      let txt = ele.text()
      info.node = ele
      _this.displayButton(ele, txt)
      if (!txt.includes('领取')) {
        txt = getTaskInfo(ele, null, null, _this) // 获取任务信息
        info.desc = txt
        let block = inBlacks(txt, info.blackList) // 是否黑名单
        logUtils.debugInfo(['{} 任务:{}', block, txt])
        if (block) {
          continue
        }
        // 任务次数超限？
        info.taskCount[txt] = info.taskCount[txt] ? info.taskCount[txt] + 1 : 1
        if (info.taskCount[txt] > info.taskCount.max) {
          info.blackList.push(txt)
          continue
        }
        _this.pushLog(txt)
        // 匹配任务时间
        let match = txt.match(/(\d+)(s|秒)/)
        info.timeout = info.timeout||3000
        if (match) {
          let addon = device.model == 'Redmi Note 5' ? 6 : 2
          info.timeout = (parseInt(match[1])+addon) * 1000
        }
      } else {
        _this.pushLog(txt)
      }
      info.end = false
      info.endCount = 0
      // 执行任务
      if (!_this.specialTask(txt, info, ele)) {
        _this.action(info)
      }

      // 返回位置不正确需要重新开始？
      let func = info.restart || setTimeout
      _this.pushLog('确认当前页面正确')
      func(info)
      if (info.end) return
      break
    }
    if (info.end && info.collect) {
      _this.pushLog('开始收集')
      info.collect(info)
    }
  }
  this.specialTask = function (taskText, info, node) {
    let finished = false
    if (taskText.includes('京豆xxx')) {
      this.displayButton(node, taskText)
      this.pushLog(taskText.split('|')[0])
      this.action(info)
      finished = true
    }
    logUtils.debugInfo(['specialTask {}', finished])
    return finished
  }
}
BeanCollector2.prototype.constructor = BeanCollector2
module.exports = new BeanCollector2()
